import { lazy, Suspense } from 'react'
import { createBrowserRouter, Navigate, redirect, RouteObject, useRouteError } from 'react-router-dom'
import { Flex, Skeleton } from 'antd'
import { getItem, TOKEN, hsHandleLoginCode, PERMISSIONROUTERLIST, __DEV__, MENUOPTIONS, setItem, USERRESULT, PERMISSIONS } from '@hs-admin/utils'
import { originMenuOptions } from '@/utils/menu'
import { codeGetToken, getUserInfo } from '@/api/login'
import { commonRouteLoader } from '@hs-admin/node'

const Layout = lazy(() => import('@/views/Layout'))
const Login = lazy(() => import('@/views/Login'))
const Overview = lazy(() => import('@/views/Overview'))
const BatchQuery = lazy(() => import('@/views/BatchQuery/index.tsx'))
const PersonalCenter = lazy(() =>
  import('@hs-server/components').then((it) => ({
    default: it.MineLayout
  }))
)
const FavorFilter = lazy(() =>
  import('@hs-server/components').then((it) => ({
    default: it.FavorFilter
  }))
)
const FavorCompany = lazy(() =>
  import('@hs-server/components').then((it) => ({
    default: it.FavorCompany
  }))
)
const MyExport = lazy(() =>
  import('@hs-server/components').then((it) => ({
    default: it.MyExport
  }))
)
const ExportCompanyList = lazy(() =>
  import('@hs-server/components').then((it) => ({
    default: it.ExportCompanyList
  }))
)
const CompanyReport = lazy(() =>
  import('@hs-server/components').then((it) => ({
    default: it.CompanyReport
  }))
)
const InnerDataServiceOrder = lazy(() =>
  import('@hs-server/components').then((it) => ({
    default: it.InnerDataServiceOrder
  }))
)
const Suggestion = lazy(() =>
  import('@hs-server/components').then((it) => ({
    default: it.Suggestion
  }))
)

const Database = lazy(() => import('@/views/Database/index.tsx'))
const SupplyChain = lazy(() => import('@/views/SupplyChain/index.tsx'))
const IndustryChain = lazy(() => import('@/views/IndustryChain/index.tsx'))
const Demo = lazy(() => import('@/views/Demo'))
const Portal = lazy(() => import('@/views/Portal'))
const CompanyDetail = lazy(() => import('@/views/CompanyDetail'))
const CompanyList = lazy(() => import('@/views/CompanyList'))

function withLoading(compnent: JSX.Element) {
  return <Suspense fallback={<Skeleton active />}>{compnent}</Suspense>
}

const routeChildren: Array<{
  name?: string
  path: string
  element: JSX.Element
  children?: any[]
  loader?: (params?: any, prefix?: string) => null
}> = [
  {
    path: '*',
    element: withLoading(<Navigate to="/overview" replace />)
  },
  {
    path: '',
    element: withLoading(<Navigate to="/overview" replace />)
  },
  {
    path: 'overview',
    element: withLoading(<Overview />)
  },
  {
    path: 'BatchQuery',
    element: withLoading(<BatchQuery />)
  },
  {
    path: 'PersonalCenter',
    element: withLoading(<PersonalCenter />),
    children: [
      {
        path: 'favorData/:tableId',
        element: withLoading(<PersonalCenter />)
      },
      {
        path: 'favorFilter',
        element: withLoading(<FavorFilter />)
      },
      {
        path: 'favorCompany',
        element: withLoading(<FavorCompany />)
      },
      {
        path: 'myExport',
        element: withLoading(<MyExport />),
        children: [
          {
            path: 'companyList',
            element: withLoading(<ExportCompanyList />)
          },
          {
            path: 'companyReport',
            element: withLoading(<CompanyReport />)
          }
        ]
      },
      {
        name: '我的订单',
        path: 'myOrder',
        children: [
          {
            name: '内部数据服务订单',
            path: 'innerDataService',
            element: withLoading(<InnerDataServiceOrder />)
          }
        ]
      }
    ]
  },

  {
    path: 'Database',
    element: withLoading(<Database />)
  },
  {
    path: 'SupplyChain',
    element: withLoading(<SupplyChain />)
  },
  {
    path: 'IndustryChain',
    element: withLoading(<IndustryChain />)
  },
  {
    path: 'suggestion',
    element: withLoading(<Suggestion />)
  }
]
if (__DEV__) {
  routeChildren.push({
    path: 'demo',
    element: withLoading(<Demo />)
  })
}
routeChildren.forEach((first) => {
  first.loader ??= commonRouteLoader
  first.children?.forEach((second) => {
    second.loader ??= commonRouteLoader
  })
})

function ErrorBoundary() {
  const error = useRouteError() as {
    message?: string
    status?: number
  }
  let text = ''
  if (error.message?.includes('Failed to fetch dynamically imported module')) {
    text = ''
    window.location.reload()
  } else if (error.message?.length) {
    text = error.message
  } else if (error.status === 404) {
    text = '页面不存在'
  } else if (error.status === 403) {
    text = '您没有该页面权限'
  } else {
    text = '未知错误'
    console.error(error)
  }
  return (
    <Flex align="center" justify="center" style={{ height: '100%' }}>
      <h1>{text}</h1>
    </Flex>
  )
}

const routeConfig: RouteObject[] = [
  {
    path: '/',
    element: withLoading(<Layout />),
    children: routeChildren,
    loader: async ({ request }) => {
      if (request.url.includes('//sjzx.')) {
        return redirect('/portal')
      }
      if (request.url.includes('/portal') || request.url.includes('/companyDetail')) {
        return null
      }
      const token = getItem(TOKEN)
      if (!token) {
        return redirect('/login')
      }
      const menuOptions = getItem(MENUOPTIONS)
      if (!menuOptions?.length) {
        return redirect('/login')
      }
      return null
    },
    errorElement: <ErrorBoundary />
  },
  {
    path: '/login',
    element: withLoading(<Login />),
    loader: async ({ request }) => {
      return hsHandleLoginCode(
        request.url,
        originMenuOptions,
        codeGetToken,
        getUserInfo,
        // 存储当前系统所有权限和用户信息
        (res) => {
          const permissions = res.permissions.map((item: any) => item.name)
          setItem(PERMISSIONS, permissions)
          setItem(USERRESULT, res)
          return permissions
        },
        (permissionRouterList) => {
          setItem(PERMISSIONROUTERLIST, [...permissionRouterList])
          const menuOptions = originMenuOptions
            .filter((ele) => !ele.hideMenu)
            .map((ele) => {
              Reflect.deleteProperty(ele, 'hideMenu')
              return ele
            })
          setItem(MENUOPTIONS, menuOptions)
        }
      )
    },
    errorElement: <ErrorBoundary />
  },
  {
    path: 'portal',
    element: withLoading(<Portal />)
  },
  {
    path: 'companyDetail',
    element: withLoading(<CompanyDetail />)
  },
  {
    path: 'detail',
    element: withLoading(<CompanyDetail />)
  },
  {
    path: 'companyList',
    element: withLoading(<CompanyList />)
  }
]

const router = createBrowserRouter(routeConfig)

// Clean up on module reload (HMR)
// https://vitejs.dev/guide/api-hmr
if (import.meta.hot) {
  import.meta.hot.dispose(() => router.dispose())
}

export default router
